package com.example.yx.demo14;


import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;

public class Proxy extends Target{

    private MethodInterceptor methodInterceptor;

    public void setMethodInterceptor(MethodInterceptor methodInterceptor) {
        this.methodInterceptor = methodInterceptor;
    }


    //所拥有的的被代理对象的方法，有n个方法，就在这里设置n个Method对象
    static Method save0;
    static Method save1;
    static Method save2;

    //
    static MethodProxy save0Proxy;
    static MethodProxy save1Proxy;
    static MethodProxy save2Proxy;

    static  {
        try {
            save0 = Target.class.getMethod("save");
            save1 = Target.class.getMethod("save", int.class);
            save2 = Target.class.getMethod("save", long.class);
            //5个参数,从前往后分别表示：目标类型、代理类型、参数是否无参以及返回值类型，增强方法名，原始方法名
            save0Proxy = MethodProxy.create(Target.class,Proxy.class,"()V","save","saveSuper");
            save1Proxy = MethodProxy.create(Target.class,Proxy.class,"(I)V","save","saveSuper");
            save2Proxy = MethodProxy.create(Target.class,Proxy.class,"(J)V","save","saveSuper");
        } catch (NoSuchMethodException e) {
            throw new NoSuchMethodError(e.getMessage());
        }
    }
    //>>>>>>>>>>>>>>>>>>>>带增强功能的方法
    @Override
    public void save() {
        try {
            methodInterceptor.intercept(this,save0,new Object[0],save0Proxy);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    @Override
    public void save(int i) {
        try {
            methodInterceptor.intercept(this,save1,new Object[]{i},save1Proxy);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    @Override
    public void save(long i) {
        try {
            methodInterceptor.intercept(this,save2,new Object[]{i},save2Proxy);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }


    //>>>>>>>>>>>>>>>>>>>>带原始功能的方法
    public void saveSuper() {
        super.save();
    }

    public void saveSuper(int i) {
        super.save(i);
    }

    public void saveSuper(long i) {
        super.save(i);
    }
}
